/*
 * BattlePetResource.cpp
 *
 *  Created on: 2013. 9. 12.
 *      Author: mega@gamevil.com
 */

#include "../User.h"
#include "../Enum.h"
#include "../engine.h"
#include "../NUtil/Utils.h"
#include "../NLogic/Item.h"
#include "../NLogic/Bag.h"
#include "../NResource/Static.h"

#include "BattlePetGachyaResource.h"

namespace ProjectZ { namespace NResource {

BattlePetGachyaResource::BattlePetGachyaResource()
{
	pBattlepetAD	= new BattlePetGachyaData;
	pBattlepetIOS	= new BattlePetGachyaData;
}

BattlePetGachyaResource::~BattlePetGachyaResource()
{
	delete pBattlepetAD;
	delete pBattlepetIOS;
}

bool BattlePetGachyaResource::LoadResource()
{
	if (false == pBattlepetAD->LoadResource(MARKET_GOOGLE, SC_KAKAO_GOOGLE))
		return false;

	if (false == pBattlepetIOS->LoadResource(MARKET_IOS, SC_KAKAO_IOS))
		return false;

	return true;
}

BattlePetGachyaData::Flyweight * BattlePetGachyaResource::GetFly(int company, int saleCode, BattlePetGachyaData::Key & clsKey)
{
	NUtil::MarketType marketType = NUtil::GetMarketType(company, saleCode);

	switch (marketType)
	{
	case NUtil::MarketType::AD_KAKAO:
		return pBattlepetAD->GetFly(clsKey);

	case NUtil::MarketType::IOS_KAKAO:
		return pBattlepetIOS->GetFly(clsKey);

	default:
		return NULL;
	}

	return NULL;
}

BattlePetGachyaData::~BattlePetGachyaData()
{
	std::for_each(clsFlyTree.begin(), clsFlyTree.end(), ProjectZ::NUtil::del_second_ptr<BATTLEPETTREE::value_type>);
}

void
BattlePetGachyaData::Clear()
{
	std::for_each(clsFlyTree.begin(), clsFlyTree.end(), ProjectZ::NUtil::del_second_ptr<BATTLEPETTREE::value_type>);
	clsFlyTree.clear();
}

bool
BattlePetGachyaData::LoadResource(int company, int saleCode)
{
	::Database::Command::Auto clsAuto(::Database::GETCOMMANDPOOL());
	clsAuto->SetQueryType(::Database::Command::SELECT);
	clsAuto->MakeQuery("SELECT NATIONAL_CODE, type, sub_type, value1, value2, value3 FROM resource_battlepetgachya WHERE company=%d AND sale_cd=%d ORDER BY type, sub_type", company, saleCode);

	if (false == ::Database::GETSESSION()->SyncExecute(1, clsAuto))
		return false;

	if( clsAuto->GetErrorIdx() != 0 )
		return false;

	if (0 == clsAuto->ResultRowCount())
		return false;

	Clear();

	while( clsAuto->Next() )
	{
		::Toolkit::Str<3> NATIONAL_CODE;
		BattlePetGachyaData::Flyweight * pFly = new BattlePetGachyaData::Flyweight;

		clsAuto->GetRecord() >> NATIONAL_CODE >> pFly->_TYPE >> pFly->_SUB_TYPE >> pFly->_VALUE1 >> pFly->_VALUE2 >> pFly->_VALUE3;

		if (0 != Config::Instance().GetResourceDatabase()._strNational.compare(NATIONAL_CODE.c_str()))
		{
			DEBUGLOG("%s:%d NATIONAL_CODE ERROR!!! Config National Code [%s] , Resource National Code [%s]",
					__FILE__, __LINE__,
					Config::Instance().GetResourceDatabase()._strNational.c_str(),
					NATIONAL_CODE.c_str());
			return false;
		}

		clsFlyTree[BattlePetGachyaData::Key(pFly->_TYPE, pFly->_SUB_TYPE)] = pFly;
	}

	return true;
}

BattlePetGachyaData::Flyweight *
BattlePetGachyaData::GetFly(BattlePetGachyaData::Key & clsKey)
{
	auto iter = clsFlyTree.find(clsKey);

	if (iter == clsFlyTree.end())
		return NULL;

	return iter->second;
}

void
BattlePetGachyaResource::BattlePetGachyaForTEST(User * pUser, int level, int quality)
{
	NLogic::Bag * pBag = pUser->GetBag(static_cast<INVEN_BAG_TYPE>(BAG_TYPE_BATTLE_PET));
	if (NULL == pBag)
		return;

	BattlePetGachyaData * pPet = GetDataPtr(pUser);
	if (NULL == pPet)
		return;

	BattlePetResource::BATTLEPETTREE & clsBattlePetTree = Static::InstancePtr()->GetBattlepetResource()->GetTree();
	BattlePetResource::BATTLEPETTREE::const_iterator citer = clsBattlePetTree.begin();

	for (; citer != clsBattlePetTree.end(); ++citer)
	{
		if (0 != citer->second->_PET_VERSION)
			continue;

		NLogic::Item::Data clsData;

		clsData.sub_type	= EnumClassItemTableType::CLASS_ITEM_TABLE_BATTLE_PET;
		clsData.bag_type	= INVEN_BAG_TYPE::BAG_TYPE_BATTLE_PET;
		clsData.class_type	= -1;
		clsData.quantity	= 1;

		clsData.level			= level;
		clsData.quality			= quality;
		clsData.eff_pos[0]		= GetBattlePetAttrType(pPet, false, -1);
		clsData.eff_type[0]		= citer->second->_BATTLE_TYPE;
		clsData.eff_type[1]		= clsData.quality + 1;

		GetBattlePetAttrValue(pPet, false, clsData, 0);
		GetBattlePetAttrValue(pPet, false, clsData, 1);
		GetBattlePetAttrValue(pPet, false, clsData, 2);
		GetBattlePetAttrValue(pPet, false, clsData, 3);
		GetBattlePetAttrValue(pPet, false, clsData, 4);

		clsData.tid				= citer->second->_ITEM_TID;
		clsData.evolve_point	= citer->second->_CHAR_TID;

		clsData.eff_value[6]	= (clsData.quality + 1) * 2 * 5;	// 최대 스태미너
		clsData.eff_value[5]	= (clsData.quality + 1) * 2 * ((rand() % 3) + 1); // 현재 스태미너

		bool bBagFull = false;
		pBag->AddItemWithData(clsData, bBagFull);
	}

}

bool
BattlePetGachyaResource::SetBaseBattlePetInfo(User * pUser, NLogic::Item::Data & clsData, int excludeType, int gachyaQuality)
{
	BattlePetGachyaData * pPet = GetDataPtr(pUser);
	if (NULL == pPet)
	{
		DEBUGLOG("%s : pPet is NULL!", __FUNCTION__);
		return false;
	}

	bool bEvent = false;

	clsData.sub_type	= EnumClassItemTableType::CLASS_ITEM_TABLE_BATTLE_PET;
	clsData.bag_type	= INVEN_BAG_TYPE::BAG_TYPE_BATTLE_PET;
	clsData.class_type	= -1;
	clsData.quantity	= 1;

	// 전투펫 레벨
	clsData.level		= 1;

	// 전투펫 등급
	clsData.quality		= 0;

	// 전투펫 속성
	clsData.eff_pos[0]	= GetBattlePetAttrType(pPet, bEvent, excludeType);

	// 전투펫 전투 타입
	clsData.eff_type[0]	= GetBattlePetBattleType(pPet, bEvent);

	// 전투펫 스킬 레벨
//	clsData.eff_type[1] = NUtil::GetRandBetween(1, clsData.quality + 1);
	clsData.eff_type[1] = clsData.quality + 1;

	// 속성 공격력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 0)) {
		return false;
	}

	// 화염 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 1)) {
		return false;
	}

	// 냉기 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 2)) {
		return false;
	}

	// 신성 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 3)) {
		return false;
	}

	// 암흑 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 4)) {
		return false;
	}

	// 전투펫 종류
	clsData.tid				= 0;
	clsData.evolve_point		= 110;
//	if (false == GetBattlePetKind(pPet, clsData, pUser->GetCharacterInfo().level)) {
//		return false;
//	}

	// 전투펫 스태미너
	// 최대 스태미나 = 등급별별수 * 스테미너상수(2) * 단계
	clsData.eff_value[6]	= (clsData.quality + 1) * 2 * 5;	// 최대 스태미너
	clsData.eff_value[5]	= (clsData.quality + 1) * 2 * ((rand() % 3) + 1); // 현재 스태미너

	return true;
}



BattlePetGachyaData *
BattlePetGachyaResource::GetDataPtr(User * pUser)
{
	NUtil::MarketType marketType = NUtil::GetMarketType(pUser->GetCompany(), pUser->GetSaleCode());

	switch (marketType)
	{
	case NUtil::MarketType::AD_KAKAO:
		return pBattlepetAD;

	case NUtil::MarketType::IOS_KAKAO:
		return pBattlepetIOS;

	default:
		return NULL;
	}

	return NULL;
}

bool
BattlePetGachyaResource::IsBattlePetGachyaEvent(User * pUser)
{
	return Static::InstancePtr()->GetEventTime()->IsBattlePetGachyaEvent(pUser);
}

int
BattlePetGachyaResource::GetBattlePetLevel(BattlePetGachyaData * pPet, bool bEvent)
{
	/*
	 * 전투펫의 레벨을 결정한다
	 */
	int type = static_cast<int>(EM_BATTLEPET_GACHYA_LEVEL_RATE);

	if (true == bEvent) {
		type = static_cast<int>(EM_BATTLEPET_GACHYA_LEVEL_RATE_EVENT);
	}

	BattlePetGachyaData::BATTLEPETTREE::const_iterator citer = pPet->GetTree().begin();

	int accRate		= 0;
	int randRate	= rand() % 1000;

	for ( ; citer != pPet->GetTree().end(); citer++)
	{
		if (citer->second->_TYPE != type)
			continue;

		accRate += citer->second->_VALUE1;

		if (randRate < accRate)
			break;
	}

	int level = NUtil::GetRandBetween(citer->second->_SUB_TYPE - 9, citer->second->_SUB_TYPE);

	return level;
}

int
BattlePetGachyaResource::GetBattlePetQuality(BattlePetGachyaData * pPet, bool bEvent, int gachyaQuality)
{
	int type = static_cast<int>(EM_BATTLEPET_GACHYA_QUALITY_RATE);

	if (true == bEvent) {
		type = static_cast<int>(EM_BATTLEPET_GACHYA_QUALITY_RATE_EVENT);
	}

	BattlePetGachyaData::BATTLEPETTREE::const_iterator citer = pPet->GetTree().begin();
	int accRate		= 0;
	int randRate	= rand() % 1000;

	for ( ; citer != pPet->GetTree().end(); citer++)
	{
		if (citer->second->_TYPE != type)
			continue;

		switch (gachyaQuality)
		{
		case 0: accRate += citer->second->_VALUE1; break;	// 최소 1성 이상
		case 1: accRate += citer->second->_VALUE2; break;	// 최소 2성 이상
		case 2: accRate += citer->second->_VALUE3; break;	// 최소 3성 이상
		}

		if (randRate < accRate)
			break;
	}

	int quality = citer->second->_SUB_TYPE;

	return quality;
}

int
BattlePetGachyaResource::GetBattlePetAttrType(BattlePetGachyaData * pPet, bool bEvent, int excludeType)
{
	/*
	 * 전투펫의 속성을 결정한다
	 * 화염, 냉기, 신성, 암흑
	 *
	 * 연속 2회 뽑힌 속성 확률 = A
	 * 뽑히지 않은 나머지 속성 확률 = B
	 * 변동될 나머지 속성 확률 = B1
	 * B1 = B * (100/(100-A))
	 */

	int type = static_cast<int>(EM_BATTLEPET_GACHYA_ATTR_TYPE_RATE);

	if (true == bEvent) {
		type = static_cast<int>(EM_BATTLEPET_GACHYA_ATTR_TYPE_RATE_EVENT);
	}

	int excludeTypeRate = 0;

	// 뽑기 속성 중복 제거
	if (-1 < excludeType)
	{
		BattlePetGachyaData::Key clsKey(type, excludeType);
		BattlePetGachyaData::Flyweight * pFly = pPet->GetFly(clsKey);

		if (NULL != pFly)
			excludeTypeRate = pFly->_VALUE1;
	}

	BattlePetGachyaData::BATTLEPETTREE::const_iterator citer = pPet->GetTree().begin();
	int accRate		= 0;
	int randRate	= rand() % 100;

	for ( ; citer != pPet->GetTree().end(); citer++)
	{
		if (citer->second->_TYPE != type)
			continue;

		if (citer->second->_SUB_TYPE == excludeType)
			continue;

		int rate = ceil(citer->second->_VALUE1 * (100 / (double)(100 - excludeTypeRate)));

		accRate += rate;

		if (randRate < accRate)
			break;
	}

	int attrType = citer->second->_SUB_TYPE;

	return attrType;
}

int
BattlePetGachyaResource::GetBattlePetBattleType(BattlePetGachyaData * pPet, bool bEvent)
{
	/*
	 * 전투펫의 전투 타입을 결정한다.
	 * 공격형, 방어형, 보조형
	 */

	int type = static_cast<int>(EM_BATTLEPET_GACHYA_BATTLE_TYPE_RATE);

	if (true == bEvent) {
		type = static_cast<int>(EM_BATTLEPET_GACHYA_BATTLE_TYPE_RATE_EVENT);
	}

	BattlePetGachyaData::BATTLEPETTREE::const_iterator citer = pPet->GetTree().begin();
	int accRate		= 0;
	int randRate	= rand() % 100;

	for ( ; citer != pPet->GetTree().end(); citer++)
	{
		if (citer->second->_TYPE != type)
			continue;

		accRate += citer->second->_VALUE1;

		if (randRate < accRate)
			break;
	}

	int battleType = citer->second->_SUB_TYPE;

	return battleType;
}

bool
BattlePetGachyaResource::GetBattlePetAttrValue(BattlePetGachyaData * pPet, bool bEvent, NLogic::Item::Data & clsData, int attrType)
{
	/*
	 * 전투펫의 속성값을 계산한다.
	 *
	 * (레벨 * 타입별 속성값 가중치 * 범위상수 / 20)
	 * 범위상수 = RANDBETWEEN(범위최소값, 범위최대값)
	 */

	int type = static_cast<int>(EM_BATTLEPET_GACHYA_ATTR_WEIGHT_CONST);

	if (true == bEvent) {
		type = static_cast<int>(EM_BATTLEPET_GACHYA_ATTR_WEIGHT_CONST_EVENT);
	}

	int level		= clsData.level;
	int battleType	= clsData.eff_type[0];

	BattlePetGachyaData::Key clsKey(type, attrType);
	BattlePetGachyaData::Flyweight * pFly = pPet->GetFly(clsKey);
	if (NULL == pFly)
	{
		DEBUGLOG("GetBattlePetAttrValue : pFly is NULL!! type=%d, attrtype=%d", type, attrType);
		return false;
	}

	int rangeConst = NUtil::GetRandBetween(BATTLE_PET_RANGE_MIN, BATTLE_PET_RANGE_MAX);

	int weight = 0;
	switch (battleType)
	{
	case 0: weight = pFly->_VALUE1; break;	// 공격형
	case 1: weight = pFly->_VALUE2; break;	// 방어형
	case 2: weight = pFly->_VALUE3; break;	// 보조형
	}

	int attrValue = (level * weight * rangeConst) / 20.0;

	switch (attrType)
	{
	case 0: clsData.eff_value[0] = attrValue; break;
	case 1: clsData.eff_value[1] = attrValue; break;
	case 2: clsData.eff_value[2] = attrValue; break;
	case 3: clsData.eff_value[3] = attrValue; break;
	case 4: clsData.eff_value[4] = attrValue; break;
	}

	return true;
}

bool
BattlePetGachyaResource::GetBattlePetKind(BattlePetGachyaData * pPet, NLogic::Item::Data & clsData, int level)
{
	/*
	 * 전투펫의 종류를 결정한다.
	 */
	int battleType	= clsData.eff_type[0];

	std::vector< BattlePetResource::Flyweight * > pFlyVector;
	pFlyVector.clear();

	BattlePetResource::BATTLEPETTREE & clsBattlePetTree = Static::InstancePtr()->GetBattlepetResource()->GetTree();
	BattlePetResource::BATTLEPETTREE::const_iterator citer = clsBattlePetTree.begin();

	for (; citer != clsBattlePetTree.end(); ++citer)
	{
		if (battleType != citer->second->_BATTLE_TYPE)
			continue;

		if (0 != citer->second->_PET_VERSION)
			continue;

		if (level < citer->second->_PET_OPEN_LEVEL)
			continue;

		pFlyVector.push_back(citer->second);
	}

	BattlePetResource::Flyweight * pFly = NULL;

	int vectorSize = pFlyVector.size();
	if (0 < vectorSize)
	{
		pFly = pFlyVector[rand() % vectorSize];
	}

	if (NULL == pFly)
	{
		DEBUGLOG("GetBattlePetKind : pFly is NULL!! vectorsize=%d", vectorSize);
		return false;
	}

	clsData.tid				= pFly->_ITEM_TID;
	clsData.evolve_point	= pFly->_CHAR_TID;

	return true;
}

bool
BattlePetGachyaResource::BattlePetGachya(User * pUser, NLogic::Item::Data & clsData, int excludeType, int gachyaQuality)
{
	BattlePetGachyaData * pPet = GetDataPtr(pUser);
	if (NULL == pPet)
	{
		DEBUGLOG("%s : pPet is NULL!", __FUNCTION__);
		return false;
	}

	bool bEvent = IsBattlePetGachyaEvent(pUser);

	clsData.sub_type	= EnumClassItemTableType::CLASS_ITEM_TABLE_BATTLE_PET;
	clsData.bag_type	= INVEN_BAG_TYPE::BAG_TYPE_BATTLE_PET;
	clsData.class_type	= -1;
	clsData.quantity	= 1;

	// 전투펫 레벨
	clsData.level		= GetBattlePetLevel(pPet, bEvent);

	// 전투펫 등급
	clsData.quality		= GetBattlePetQuality(pPet, bEvent, gachyaQuality);

	// 전투펫 속성
	clsData.eff_pos[0]	= GetBattlePetAttrType(pPet, bEvent, excludeType);

	// 전투펫 전투 타입
	clsData.eff_type[0]	= GetBattlePetBattleType(pPet, bEvent);

	// 전투펫 스킬 레벨
//	clsData.eff_type[1] = NUtil::GetRandBetween(1, clsData.quality + 1);
	clsData.eff_type[1] = clsData.quality + 1;

	// 속성 공격력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 0)) {
		return false;
	}

	// 화염 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 1)) {
		return false;
	}

	// 냉기 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 2)) {
		return false;
	}

	// 신성 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 3)) {
		return false;
	}

	// 암흑 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsData, 4)) {
		return false;
	}

	// 전투펫 종류
	if (false == GetBattlePetKind(pPet, clsData, pUser->GetCharacterInfo().level)) {
		return false;
	}

	// 전투펫 스태미너
	// 최대 스태미나 = 등급별별수 * 스테미너상수(2) * 단계
	clsData.eff_value[6]	= (clsData.quality + 1) * 2 * 5;	// 최대 스태미너
	clsData.eff_value[5]	= (clsData.quality + 1) * 2 * ((rand() % 3) + 1); // 현재 스태미너

	return true;
}


int
BattlePetGachyaResource::BattlePetCombine(User * pUser, NLogic::Item::Data & clsBase , NLogic::Item::Data & clsMaterial, int combineType)
{
	BattlePetGachyaData * pPet = GetDataPtr(pUser);

	if (NULL == pPet)
	{
		DEBUGLOG("%s : pPet is NULL!", __FUNCTION__);
		return ACK_UNKNOWN_ERROR;
	}

	NResource::BalanceData * pBalance = NResource::Static::InstancePtr()->GetBalance()->GetBalancePtr(pUser);

	if (NULL == pBalance)
	{
		DEBUGLOG("%s : pBalance is NULL!", __FUNCTION__);
		return ACK_UNKNOWN_ERROR;
	}

	bool bEvent = IsBattlePetGachyaEvent(pUser);

	// 기준펫의 등급 상승여부 계산
	BattlePetGachyaData::Key baseKey(EM_BATTLEPET_GACHYA_COMBINE_RATE, clsBase.quality);
	BattlePetGachyaData::Flyweight * pFly = pPet->GetFly(baseKey);
	if (NULL == pFly)
	{
		DEBUGLOG("%s : pFly is NULL!! type=8, quality=%d", __FUNCTION__, clsBase)
		return ACK_UNKNOWN_ERROR;
	}

	// 스태미너 회복
	// 재료 전투펫 등급 * 스태미너 회복 상수
	int restoreStamina = (clsMaterial.quality + 1) * pBalance->GetValue(EM_STAMINA_RECORVERY_CONST);
	clsBase.eff_value[5] += restoreStamina;

	// 6성이상의 전투펫을 합성시 실패 리턴
	if (clsBase.quality >= 5)
	{
		// 회복된 스태미너가 최대 스태미너보다 큰 경우 최대 스태미너로 설정
		if (clsBase.eff_value[5] > clsBase.eff_value[6])
		{
			clsBase.eff_value[5] = clsBase.eff_value[6];
		}

		return ACK_BATTLEPET_COMBINE_FAIL;
	}

	// 합성 타입에 따른 확률 계산
	int qualityRate = 0;

	if (combineType == 0)
	{
		// 일반 합성 (골드 소모)
		qualityRate = pFly->_VALUE1 + pFly->_VALUE3;
	}
	else
	{
		// 특수 합성 (젠 소모)
		qualityRate = pFly->_VALUE2 + pFly->_VALUE3;
	}

	int randRate = rand() % 100;

	// 합성 실패
	if (qualityRate < randRate)
	{
		// 회복된 스태미너가 최대 스태미너보다 큰 경우 최대 스태미너로 설정
		if (clsBase.eff_value[5] > clsBase.eff_value[6])
		{
			clsBase.eff_value[5] = clsBase.eff_value[6];
		}

		return ACK_BATTLEPET_COMBINE_FAIL;
	}

	// 합성 성공
	clsBase.quality += 1;

	// 합성에 성공하는 경우 최대 스태미너 갱신
	clsBase.eff_value[6] = (clsBase.quality + 1) * 2 * 5;

	// 회복된 스태미너가 최대 스태미너보다 큰 경우 최대 스태미너로 설정
	if (clsBase.eff_value[5] > clsBase.eff_value[6])
	{
		clsBase.eff_value[5] = clsBase.eff_value[6];
	}

	// 전투펫 스킬 레벨
	clsBase.eff_type[1] = clsBase.quality + 1;

	// 속성 공격력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsBase, 0)) {
		return ACK_UNKNOWN_ERROR;
	}

	// 화염 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsBase, 1)) {
		return ACK_UNKNOWN_ERROR;
	}

	// 냉기 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsBase, 2)) {
		return ACK_UNKNOWN_ERROR;
	}

	// 신성 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsBase, 3)) {
		return ACK_UNKNOWN_ERROR;
	}

	// 암흑 방어력
	if (false == GetBattlePetAttrValue(pPet, bEvent, clsBase, 4)) {
		return ACK_UNKNOWN_ERROR;
	}

	return ACK_OK;
}

int
BattlePetGachyaResource::BattlePetEvolution(User * pUser, NLogic::Item::Data & clsData,
		NLogic::Item::Data & clsDataMaterial, int materialCount,
		NLogic::Item::Data & clsDataMaterial2, int materialCount2)
{
	BattlePetGachyaData * pPet = GetDataPtr(pUser);

	if (NULL == pPet)
	{
		DEBUGLOG("%s : pPet is NULL!", __FUNCTION__);
		return ACK_UNKNOWN_ERROR;
	}

	// 6성이하 전투펫은 진화 불가
	if (clsData.quality < 5)
	{
		return ACK_PET_GRADE_MISMATCH;
	}

	int possessCount	= clsDataMaterial.quantity - materialCount;
	int possessCount2	= clsDataMaterial2.quantity - materialCount2;

	// 진화 재료 부족
	if (possessCount < 0 || possessCount2 < 0)
	{
		return ACK_PET_MATERIAL_LACK;
	}

	// 진화
	clsData.quality += 1;

	// 전투펫 스킬 레벨
	clsData.eff_type[1] = clsData.quality + 1;

	// 진화 재료 차감
	clsDataMaterial.quantity = possessCount;
	clsDataMaterial2.quantity = possessCount2;

	return ACK_OK;
}

int
BattlePetGachyaResource::BattlePetEvolutionV2(User * pUser, NLogic::Item * pItem)
{
	// 6성이하 전투펫은 진화 불가
	if (pItem->GetData().quality < 5)
	{
		return ACK_PET_GRADE_MISMATCH;
	}

	UltimateEvolutionRateResource::Flyweight * pFly = Static::InstancePtr()->GetUltimateRateResource()->GetFly(pItem->GetData().quality);
	if (NULL == pFly)
	{
		DEBUGLOG("%s : pFly is NULL!", __FUNCTION__);
		return ACK_UNKNOWN_ERROR;
	}

	int randRate = rand() % 100;

	// 진화 실패
	if (pFly->_BATTLEPET < randRate)
	{
		return ACK_BATTLEPET_EVOLUTION_FAIL;
	}

	// 진화
	pItem->GetData().quality += 1;

	// 전투펫 스킬 레벨
	pItem->GetData().eff_type[1] = pItem->GetData().quality + 1;

	return ACK_OK;
}

void
BattlePetGachyaResource::AddBattlePetHP(User * pUser, int petType, int & hp)
{
	/*
	 * 타입별로 전투펫의 HP에 가중치를 더해 준다
	 */

	BattlePetGachyaData * pPet = GetDataPtr(pUser);

	if (NULL == pPet)
	{
		DEBUGLOG("%s : pPet is NULL!", __FUNCTION__);
		return;
	}

	BattlePetGachyaData::Key clsKey(EM_BATTLEPET_GACHYA_ABLITY_WEIGHT_CONST, 2);	// 전투펫 타입별 체력 가중치
	BattlePetGachyaData::Flyweight * pFly = pPet->GetFly(clsKey);

	if (NULL == pFly)
	{
		DEBUGLOG("%s : pFly is NULL!", __FUNCTION__);
		return;
	}

	switch (petType)
	{
	case 0: hp = (hp * pFly->_VALUE1) / 100; break;
	case 1: hp = (hp * pFly->_VALUE2) / 100; break;
	case 2: hp = (hp * pFly->_VALUE3) / 100; break;
	}
}

} /* NResource */ } /* ProjectZ */
